<?php
class ZendX_Model_Base {
	public function fromArray(array $options)
    {
    	$options = $this->_setReferences($options);
    	
        $methods = get_class_methods($this);
        foreach ($options as $key => $value) 
        {
            $method = 'set' . ucfirst($key);
            if (in_array($method, $methods)) 
            {
            	$data = array();
            	$data[$key] = $value;            	
            	call_user_func_array(array($this, $method), $data);
            }
        }
        return $this;
    }
        
    public function __set ($name, $value)
    {
        $method = 'set' . $name;
        if (! method_exists($this, $method)) {
            throw new Exception('Invalid property');
        }
        $this->$method($value);
    }
    public function __get ($name)
    {
        $method = 'get' . $name;
        if (! method_exists($this, $method)) {
            throw new Exception('Invalid property');
        }
        return $this->$method();
    }
    
	/**
     * Creates for association fields a reference instead of the id itself.
     */
    private function _setReferences(array $post)
    {
    	$registry = Zend_Registry::getInstance();
    	$em = $registry->entityManager;
    	
        $metadata = $em->getClassMetadata(get_class($this));

        foreach ($post as $fieldName => $value) 
        {
            if (isset($metadata->associationMappings[$fieldName])) 
            {
                if( isset($metadata->associationMappings[$fieldName]['nullable'])
                && $metadata->associationMappings[$fieldName]['nullable'] == 1 && $value == '')
        		{
        			$post[$fieldName] = NULL;
        		}
        	
                if (empty($value)) 
                {
                    $post[$fieldName] = NULL;
                } 
                else 
                {
                    $targetEntity = $metadata->associationMappings[$fieldName]['targetEntity'];
                    if (is_array($value)) 
                    {
                    	if (count(array_filter(array_keys($value),'is_string')) == count($value))
                    	{
                    		$method = 'get' . ucfirst($fieldName);
                    		if (! method_exists($this, $method)) 
                    		{
            					throw new Exception('Invalid property');
        					}
        					$obj = $this->$method();
        					
                    		if (is_null($obj)) 
                    		{                    				
                    			$obj = new $targetEntity();
                    		}
                    		
                    		$obj->fromArray($value);
                    		$post[$fieldName]=$obj;
                    	}
                    	else 
                    	{
                    		$data = array();
                    		foreach ($value as $key)
                    		{
                    			$data[] =  $em->getRepository($targetEntity)->find($key);
                    		}
                    		$post[$fieldName] = $data;
                    	}
                    }
                    else 
                    	$post[$fieldName] = $em->getRepository($targetEntity)->find($value);
                }
            }
        }
        
        return $post;
    }
}

?>